Conversation
There was a problem hiding this comment.
Pull request overview
Introduces the first working implementation of django-knobs: a Django app for dynamic, runtime-editable configuration/feature flags, backed by a DB table with an in-process cache, an admin UI, and optional history tracking.
Changes:
- Adds core library modules (registry/coercion, local cache, admin UI, DB model + migrations, sync thread, signals).
- Adds optional
django-simple-historyintegration and an example Django app showcasing usage. - Adds docs site config/content plus CI workflows (tests, docs deploy, PyPI release) and packaging/dependency setup.
Reviewed changes
Copilot reviewed 46 out of 54 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| zensical.toml | Adds Zensical documentation site configuration/navigation. |
| uv.lock | Locks Python dependencies for reproducible installs. |
| tests/conftest.py | Minimal Django settings for pytest runs. |
| tests/test_cache.py | Tests for thread-safe in-process cache behavior. |
| tests/test_proxy.py | Tests for proxy access to registered knobs via attribute lookup. |
| tests/test_registry.py | Tests for coercion/serialization and type inference from defaults. |
| tests/test_sync.py | Tests for DB sync behavior and post-save cache update. |
| src/knobs/cache.py | Implements LocalCache and a module-global cache instance. |
| src/knobs/conf.py | Adds KNOBS settings wrapper and serializer loader. |
| src/knobs/serializers.py | Defines serializer protocol + JSON serializer implementation. |
| src/knobs/registry.py | Defines Knob, coercion/serialization logic, and registry builder. |
| src/knobs/proxy.py | Adds KnobsProxy and exported config accessor. |
| src/knobs/models.py | Adds KnobValue model to store raw values + update timestamp. |
| src/knobs/migrations/init.py | Initializes migrations package. |
| src/knobs/migrations/0001_knob_values_table.py | Creates the KnobValue table. |
| src/knobs/signals.py | Updates cache on KnobValue saves and emits change signals. |
| src/knobs/sync.py | Background thread polling DB changes and reloading cache. |
| src/knobs/apps.py | App startup wiring: build registry + optionally start sync thread. |
| src/knobs/admin.py | Custom admin UI to view/edit knobs with type-aware widgets. |
| src/knobs/templates/admin/knobs/knobvalue/knobs_form.html | Admin template for grouped knob editing. |
| src/knobs/init.py | Exposes Knob and config as public API. |
| src/knobs/py.typed | Marks package as typed for type checkers. |
| src/knobs/contrib/history/init.py | Documents/exports optional history integration config. |
| src/knobs/contrib/history/config.py | Registers history admin for historical knob values. |
| src/knobs/contrib/history/models.py | Registers KnobValue with django-simple-history. |
| src/knobs/contrib/history/migrations/init.py | Initializes history migrations package. |
| src/knobs/contrib/history/migrations/0001_initial.py | Creates historical table for knob changes. |
| example_app/manage.py | Adds runnable example project entrypoint. |
| example_app/example_app/init.py | Initializes example project package. |
| example_app/example_app/settings.py | Example project settings + KNOBS_CONFIG/KNOBS usage. |
| example_app/example_app/urls.py | Example URLs incl. admin + demo endpoints. |
| example_app/example_app/wsgi.py | Example WSGI application entrypoint. |
| example_app/showcase/init.py | Initializes showcase app package. |
| example_app/showcase/apps.py | Example app wiring to log knob changes via signal. |
| example_app/showcase/views.py | Example views reading knobs and exposing a JSON endpoint. |
| example_app/showcase/templates/showcase/base.html | Base template for the showcase UI. |
| example_app/showcase/templates/showcase/index.html | Showcase page rendering various knob types. |
| example_app/showcase/templates/showcase/maintenance.html | Maintenance page toggled by a knob. |
| docs/quickstart.md | Adds quickstart guide for installation and basic usage. |
| docs/settings.md | Documents available KNOBS settings and serializer support. |
| docs/caching.md | Explains caching model, sync thread behavior, and signals. |
| docs/extensions/history.md | Documents django-simple-history integration and usage. |
| docs/assets/banner.png | Adds README/docs banner image asset. |
| README.md | Expands README with install/setup instructions and badges. |
| pyproject.toml | Defines package metadata, dependencies, tooling (pytest/ruff), build backend. |
| Makefile | Adds helper targets for running example app + infra. |
| docker-compose.yml | Adds Postgres service for local example app runs. |
| .pre-commit-config.yaml | Adds Ruff and basic whitespace hooks. |
| .github/dependabot.yml | Enables dependabot for uv + GitHub Actions. |
| .github/workflows/code-check.yml | Adds CI tests for Python 3.12/3.13 with Postgres service. |
| .github/workflows/release-docs.yml | Adds docs build/deploy pipeline using uv + Zensical. |
| .github/workflows/docs.yml | Adds an additional docs deploy workflow (overlaps release-docs). |
| .github/workflows/release-pypi.yml | Adds PyPI publishing workflow via uv build + trusted publishing. |
| LICENSE | Provides MIT license text. |
| .gitignore | Adds ignore rules for repo artifacts. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| from django.db import ProgrammingError | ||
|
|
||
| from knobs.cache import _cache | ||
| from knobs.conf import knobs_settings | ||
| from knobs.registry import _registry | ||
| from knobs.sync import SyncThread | ||
|
|
||
| thread = SyncThread(knobs_settings.SYNC_INTERVAL, _cache, _registry) | ||
| try: | ||
| thread._sync() | ||
| except ProgrammingError: | ||
| logger.warning("django-knobs: table not found, skipping startup sync (run migrate)") | ||
| return # table doesn't exist yet — don't start the background thread |
There was a problem hiding this comment.
thread._sync() can fail with OperationalError (e.g., missing table on SQLite) as well as ProgrammingError depending on the DB backend/driver. Consider catching django.db.utils.OperationalError (or a broader DatabaseError) in addition to ProgrammingError so startup sync reliably skips when migrations haven't run yet.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
No description provided.